<?php
namespace app\service\MessageParser;

use think\facade\Log;

/**
 * 现有厂商消息解析器
 * 解析原有的MQTT消息格式
 */
class Vendor1MessageParser implements MessageParserInterface
{
    /**
     * 解析器名称
     */
    private const PARSER_NAME = 'Vendor1 Message Parser';

    /**
     * 解析器版本
     */
    private const PARSER_VERSION = '1.0';

    /**
     * 判断是否能处理该消息
     * Vendor1协议的特征：包含device_info、hotspot_info等嵌套结构
     * 
     * @param string $topic MQTT主题
     * @param array $messageData 消息数据
     * @return bool
     */
    public function canHandle(string $topic, array $messageData): bool
    {
        // 检查是否包含Vendor1特有的字段
        $hasVendor1Fields = isset($messageData['device_info']) || 
                           isset($messageData['hotspot_info']) ||
                           isset($messageData['system_info']);

        // 检查主题是否符合Vendor1格式
        $isVendor1Topic = strpos($topic, 'tc/device/out/') === 0;

        $canHandle = $hasVendor1Fields && $isVendor1Topic;

        return $canHandle;
    }

    /**
     * 解析消息
     * 
     * @param string $topic MQTT主题
     * @param array $messageData 消息数据
     * @param string $deviceId 设备标识
     * @return array|null
     */
    public function parse(string $topic, array $messageData, string $deviceId = ''): ?array
    {
        try {
            Log::info("【Vendor1MessageParser】开始解析消息，主题: {$topic}");

            // 从主题中提取MAC地址
            $topicParts = explode('/', $topic);
            $deviceMac = $topicParts[3] ?? $deviceId;

            // 判断协议类型：是否存在 hotspot_info_5g 字段
            $is5GProtocol = isset($messageData['hotspot_info_5g']);

            Log::info("【Vendor1MessageParser】检测到协议类型: " . ($is5GProtocol ? '5G协议' : '4G协议'));

            // 获取设备信息
            $deviceInfo = $messageData['device_info'] ?? [];
            $systemInfo = $messageData['system_info'] ?? [];
            $networkInfo = $messageData['network_info'] ?? [];
            $simInfo = $messageData['sim_info'] ?? [];

            // 根据协议类型获取热点信息
            if ($is5GProtocol) {
                // 5G协议：使用 hotspot_info_5g 作为主要热点信息
                $hotspotInfo = $messageData['hotspot_info_5g'] ?? [];
                $hotspotInfo5g = $messageData['hotspot_info_5g'] ?? [];
            } else {
                // 4G协议：只有 hotspot_info，没有 hotspot_info_5g
                $hotspotInfo = $messageData['hotspot_info'] ?? [];
                $hotspotInfo5g = [];
            }

            // 获取当前生效的SIM卡信息
            $currentSimId = $messageData['cur_sim_id'] ?? 1;
            $currentSim = $this->getCurrentSimInfo($simInfo, $currentSimId, $is5GProtocol);

            // 准备保存的数据
            $saveData = [
                'IMEI' => $deviceInfo['dev_imei2'] ?? '',
                'mac' => $deviceMac,
                'iccid' => $currentSim['sim_iccid'] ?? '',
                'signal_strength' => $currentSim['sim_signal_level'] ?? 4,
                'mnc' => $this->getMncType($currentSim['sim_mnc'] ?? '00'),
                'ssid' => $hotspotInfo['hotspot_name'] ?? '',
                'key' => $hotspotInfo['hotspot_password'] ?? '',
                'main_sim' => $currentSimId,
                'user_sim' => $currentSimId,
                'band' => $this->getBandType($hotspotInfo, $hotspotInfo5g, $is5GProtocol),
                'hidden_ssid' => $hotspotInfo['hotspot_whether_hide'] ?? 0,
                'conn_cnt' => $hotspotInfo['hotspot_connected_num'] ?? 0,
                'remain_pwr' => $this->getBatteryLevel($systemInfo),
                'dbm' => $currentSim['sim_dbm'] ?? '',
                'update_time' => date('Y-m-d H:i:s'),
            ];

            // 根据运营商设置对应的号段字段
            if ($currentSim) {
                $operator = $this->getOperatorByMnc($currentSim['sim_mnc'] ?? '00');
                $phoneNumber = $this->extractPhoneNumber($currentSim['sim_iccid'] ?? '');

                switch ($operator) {
                    case 'mobile':
                        $saveData['yidong_kahao'] = $phoneNumber;
                        break;
                    case 'unicom':
                        $saveData['liangtong_kahao'] = $phoneNumber;
                        break;
                    case 'telecom':
                        $saveData['dianxin_kahao'] = $phoneNumber;
                        break;
                }
            }

            $iccid = isset($currentSim['sim_iccid']) ? $currentSim['sim_iccid'] : '';
            Log::info("【Vendor1MessageParser】设备数据解析完成: 协议=" . ($is5GProtocol ? '5G' : '4G') . ", IMEI={$saveData['IMEI']}, MAC={$saveData['mac']}, ICCID={$iccid}, 频段={$saveData['band']}");

            return $saveData;

        } catch (\Throwable $e) {
            Log::error('【Vendor1MessageParser】解析设备消息失败: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * 获取当前SIM卡信息
     * @param array $simInfo SIM卡信息数组
     * @param int $currentSimId 当前SIM卡ID
     * @param bool $is5GProtocol 是否为5G协议
     * @return array|null 当前SIM卡信息
     */
    private function getCurrentSimInfo(array $simInfo, int $currentSimId, bool $is5GProtocol): ?array
    {
        Log::info("【Vendor1MessageParser】开始获取SIM卡信息，SIM ID: {$currentSimId}");

        foreach ($simInfo as $sim) {
            if (($sim['sim_id'] ?? 0) == $currentSimId && ($sim['sim_exist'] ?? 0) == 1) {
                Log::info("【Vendor1MessageParser】找到有效的SIM卡，ICCID: " . ($sim['sim_iccid'] ?? ''));

                // 处理不同协议中字段的差异
                if (!$is5GProtocol) {
                    // 4G协议中，某些字段可能有不同的格式
                    // 例如：sim_dbm 在4G中可能是 "-71dBm" 格式，需要提取数值
                    if (isset($sim['sim_dbm']) && is_string($sim['sim_dbm'])) {
                        Log::info("【Vendor1MessageParser】4G协议，处理sim_dbm格式: " . $sim['sim_dbm']);
                        // 提取数值部分，去掉 "dBm" 后缀
                        $sim['sim_dbm'] = (int)filter_var($sim['sim_dbm'], FILTER_SANITIZE_NUMBER_INT);
                        Log::info("【Vendor1MessageParser】处理后的sim_dbm: " . $sim['sim_dbm']);
                    }
                }
                return $sim;
            }
        }

        Log::warning("【Vendor1MessageParser】未找到有效的SIM卡，SIM ID: {$currentSimId}");
        return null;
    }

    /**
     * 获取MNC类型数字
     * @param string $mnc MNC代码
     * @return int 类型数字
     */
    private function getMncType(string $mnc): int
    {
        switch ($mnc) {
            case '00':
            case '02':
            case '07':
            case '08':
                return 0; // 移动
            case '01':
            case '06':
            case '09':
                return 1; // 联通
            case '03':
            case '05':
            case '11':
                return 2; // 电信
            default:
                return 0; // 默认移动
        }
    }

    /**
     * 获取频段类型
     * @param array $hotspotInfo 热点信息
     * @param array $hotspotInfo5g 5G热点信息
     * @param bool $is5GProtocol 是否为5G协议
     * @return string 频段类型 ('a' 或 'g')
     */
    private function getBandType(array $hotspotInfo, array $hotspotInfo5g, bool $is5GProtocol): string
    {
        if ($is5GProtocol) {
            // 5G协议：检查 hotspot_info_5g 的 hotspot_whether_5g 字段
            return ($hotspotInfo5g['hotspot_whether_5g'] ?? 0) == 1 ? 'a' : 'g';
        } else {
            // 4G协议：检查 hotspot_info 的 hotspot_band 字段
            // hotspot_band: 0=2.4G, 1=5G
            return ($hotspotInfo['hotspot_band'] ?? 0) == 1 ? 'a' : 'g';
        }
    }

    /**
     * 获取电池电量
     * @param array $systemInfo 系统信息
     * @return int 电池电量
     */
    private function getBatteryLevel(array $systemInfo): int
    {
        // 5G协议使用 sys_bat_level，4G协议也使用 sys_bat_level
        // 但4G协议中可能有拼写错误的字段名
        return $systemInfo['sys_bat_level'] ?? $systemInfo['sys_battery_level'] ?? 0;
    }

    /**
     * 根据MNC获取运营商类型
     * @param string $mnc MNC代码
     * @return string 运营商类型 ('mobile', 'unicom', 'telecom')
     */
    private function getOperatorByMnc(string $mnc): string
    {
        switch ($mnc) {
            case '00':
            case '02':
            case '07':
            case '08':
                return 'mobile'; // 移动
            case '01':
            case '06':
            case '09':
                return 'unicom'; // 联通
            case '03':
            case '05':
            case '11':
                return 'telecom'; // 电信
            default:
                return 'mobile'; // 默认移动
        }
    }

    /**
     * 从ICCID提取电话号码
     * @param string $iccid ICCID
     * @return string 电话号码
     */
    private function extractPhoneNumber(string $iccid): string
    {
        // ICCID格式：89[国家代码][运营商代码][号码]
        // 通常电话号码在ICCID的第7-20位
        if (strlen($iccid) >= 20) {
            return substr($iccid, 6, 14);
        }
        return '';
    }

    /**
     * 获取解析器名称
     */
    public function getName(): string
    {
        return self::PARSER_NAME;
    }

    /**
     * 获取解析器版本
     */
    public function getVersion(): string
    {
        return self::PARSER_VERSION;
    }
}

